# -*- shell-script -*-
#
# "Control" for "Tank" Simulation
#

record(ao, "$(user):setpoint")
{
    field(DESC, "Temperature Setpoint")
    field(EGU, "C")
    field(HOPR, "100")
    field(LOPR, "0")
    field(DRVL, "0")
    field(DRVH, "100")
    field(HIHI, "90")
    field(HIGH, "80")
    field(LOW , "0")
    field(LOLO, "0")
    field(PREC, "1")
    field(DOL,  "30")
    field(PINI, "YES")
}

# Temperature error
# A - current temperature
# B - setpoint
record(calc, "$(user):error")
{
    field(DESC, "Temperature Error")
    field(SCAN, ".5 second")
    field(INPA, "$(user):setpoint")
    field(INPB, "$(user):tank MS")
    field(CALC, "A-B")
    field(PREC, "1")
    field(FLNK, "$(user):integral")
}

# Integrate error (A) but assert that
# it stays within limits (C)
record(calc, "$(user):integral")
{
    field(DESC, "Integrate Error for PID")
    field(PREC, "3")
    field(INPA, "$(user):error PP MS")
    field(INPB, "$(user):integral")
    field(INPC, "20.0")
    field(CALC, "(B+A>C)?C:(B+A<-C)?(-C):(B+A)")
    field(FLNK, "$(user):PID")
}

# Every second, calculate new heater voltage via PID (PI)
# A - Kp
# B - error
# C - Ki
# D - error integral
record(calc, "$(user):PID")
{
    field(DESC, "Water Tank PID")
    field(PREC, "3")
    field(LOPR, "-1000")
    field(HOPR, "1000")
    field(HIHI, "900")
    field(HIGH, "500")
    field(LOW , "-500")
    field(LOLO, "-900")
    field(INPA, "10.0")
    field(INPB, "$(user):error MS")
    field(INPC, "5.0")
    field(INPD, "$(user):integral MS")
    field(CALC, "A*B+C*D")
}

# Patch tank.db:
record(ao, "$(user):heat_V")
{
    field(DOL, "$(user):PID MS")
    field(OMSL,"closed_loop")
}



